\chapter{tentmaker Reference}
\label{chap:tentref}

This chapter explains how to start tentmaker, then gives a careful guided
tour of its tabs.

\section{Starting Tentmaker}

There are three ways to start
tentmaker,\index{tentmaker!starting methods}
pick one each time you use it.
All of them allow an optional port flag \verb+-p+ or \verb+--port+,
which changes the default port from 8080.

\subsection{Starting tentmaker in normal mode}

If you are happy with the table structure of your app, but you need to
work on some of its details, start tentmaker in this most common way:
{\footnotesize
\begin{verbatim}
tentmaker file.bigtop
\end{verbatim}
}
\noindent
If you leave out the file name, tentmaker will start in default mode.
While you could make an app from scratch from there, I'm far too lazy
for that.  Instead, I either start tentmaker using one of the methods below,
or use bigtop with the same flags.

\subsection{Starting an app from scratch with tentmaker}

Use the \verb+-n+ or \verb+--new+\index{--new or -n!tentmaker flag}
flag to start a brand new app\index{tentmaker!brand new app}
in tentmaker.  This flag
expects an application name and an optional list of table relationships,
like this:

{\footnotesize
\begin{verbatim}
tentmaker -n Sample table1 table2
\end{verbatim}
}

Keep in mind that tentmaker is not all that smart.  If you name one of
your tables with an SQL reserved word\footnote{table being the most popular}
it won't know or care or try to stop you.

\subsection{Adding tables to an app with tentmaker}

If you already have a bigtop file, you may choose to
augment\index{tentmaker!augmenting}
it with
tentmaker.  While you could just start tentmaker in normal mode and do
all the work, you could also say something like this:

{\footnotesize
\begin{verbatim}
tentmaker -a docs/sample.bigtop table3 table4
\end{verbatim}
}

\subsection{Table relationships on the command line}

You can run both tentmaker\index{tentmaker!flags}
and bigtop\index{bigtop!flags} with the new and add mode
flags shown above.  In addition to merely adding tables, you can show
table relationships during this step.  For example, suppose I have a
new app like the one in Chapter \ref{chap:jobadsapp}, which needs to track a
hiring process.  For a start it will have
tables for job descriptions, job skills, and open positions.  I could
create the app like this:

{\footnotesize
\begin{verbatim}
tentmaker -n Hiring 'pos->job job<->skill'
\end{verbatim}
}

This will start tentmaker.  If you wanted to build the app directly
and delay or completely avoid tentmaker, you could substitute bigtop
for tentmaker\index{tentmaker!app creation}:

{\footnotesize
\begin{verbatim}
bigtop -n Hiring 'pos->job job<->skill'
\end{verbatim}
}

The details of table relationships are covered near the beginning
of Section \ref{sec:asciiart} and the relationship operators are
summarized in Table \ref{tab:asciiart}.

\section{Tentmaker's Tabs}

Recall from Chapter \ref{chap:simpleex} that there are five tabs in
tentmaker.  For ease of reference, I reproduced the table summarizing
them as Table \ref{tab:tenttabs2}.
Here we will walk through them in detail.

\begin{table}
\begin{center}
\begin{tabular}{l|l}
Tab Label & Allows you to specify... \\
\hline
Bigtop Config &
    the name of the app and a choice of \\
 &  engines to serve it \\

App Body &
    the meat of your app, i.e. your tables \\
 &  and controllers \\

Backends &
    the list of all things bigtop should \\
 &  make for you.  Use check boxes to    \\
 &  choose what you want it to do and    \\
 &  input boxes to configure each        \\
 &  backend's output. \\

App Level Statements &
    author names, their email addresses, \\
 &  project license, etc., all of these  \\
 &  have nice defaults \\

App Config &
    a single input table for app \\
 &  configuration \\
\end{tabular}
\end{center}
\caption{The five tabs of tentmaker (same as Table \ref{tab:tenttabs1}).}
\label{tab:tenttabs2}
\end{table}

\subsection{Bigtop Config\index{tentmaker!Bigtop Config tab}}

Let's start the Bigtop Config\index{Bigtop Config, tentmaker tab}
tab tour at the bottom and move up.  At
the bottom is a dump of the
current bigtop source.  This is mostly for debugging purposes, but look
it over periodically as you have interest.  It is sometimes helpful
when tracking problems.

Immediately above the dump is a
`Save As:'\index{saving, in tentmaker}\index{tentmaker!saving}
button and a file name
box.  When you've made constructive changes, double check the file name and
press the button.  A message will appear, immediately below the button,
telling you how that went.

To the left of the `Save As:' button is a button labeled `Stop
Server.'\index{stopping tentmaker}\index{tentmaker!stopping server}
Using it is the preferred way to stop tentmaker, because
the browser will continue to pretend the app is working after you kill
tentmaker with ctrl-C.  If you press `Stop Server,'
tentmaker will set a javascript flag to tell you that the server is stopped
whenever you try to use it.  When you restart the server, you must request
a hard refresh, which also eliminates most caching issues.

The top of the tab is more interesting.  Here you can change the
name\index{tentmaker!app name change} of the
app (which is much easier before initial generation).  You can also choose
a server engine\index{tentmaker!engine selection}
and a template engine.\index{tentmaker!template engine selection}
It is slightly easier to start with
the CGI engine and Gantry's stand alone server.  In Chapter \ref{chap:deploy},
we saw how to move to \verb+mod_perl+.

In our shop we like Template Toolkit well enough that we have not added
support to Gantry for any other templating system.  The other alternative
is Default,\index{template!engine!Default}
which turns off templating.  Even with templating off, you
can still get HTML generation help from Gantry.  The case study in
Chapter \ref{chap:contactus} does this.  You can even use the Template
Toolkit engine manually, when you need to construct special output like
AJAX responses, see Subsection \ref{ssec:templateproc} for an example.

You could also write your own template engine plugin, see
Section \ref{sec:templateengineapi} for advice.
That is really all there is to say about the first tab.

\subsection{App Body\index{tentmaker!App Body tab}}

We already had some quick tours through the app
body\index{App Body tentmaker tab}
in prior chapters.  Here we will walk more slowly.
The app body is made up of one or more blocks and statements.  All statements
are managed on the `App Level Statements' tab.  Each block has a type,
most have names.  In the bigtop source file, config is one of the app body
blocks.  It has its own tab.  All of the other types are managed through
this tab.
The blocks you can create are shown in Table \ref{tab:tentblocks}.
Let's look at what you can control for each of these.

\begin{table}
\begin{center}
\begin{tabular}{l|l}
Type & Description \\
\hline
Table      & makes an SQL table and corresponding \\
           & controller                           \\
Controller & makes a perl module                                          \\
Base Controller & makes the base perl module (you can have \\
                & only one)      \\
Literal    & puts literal text into one or more \\
           & output files              \\
Join Table & indicates two tables which share \\
           & a many-to-many \\
           & relationship \\
Schema     & (PostgreSQL only) makes an SQL schema                        \\
Sequence   & (rarely used) makes an SQL sequence and \\
           & corresponding table and controller (useful \\
           & for PostgreSQL only)
\end{tabular}
\end{center}
\caption{App Body blocks tentmaker can make for you.}
\label{tab:tentblocks}
\end{table}

\subsubsection{Table}

When you open a
table\index{table editing in tentmaker}\index{tentmaker!table editing}
for editing, you see something like Figure \ref{fig:tableedit2}.
From this we see four statements which affect a whole table.  They
are summarized in Table \ref{tab:tablestats1}.
If the table
might offend one of the backends, you can highlight
\verb+not_for+\index{not for@\verb+not_for+ SQL and/or Model}
for
that backend.  For instance, if you want models for tables that are in
an external database, you can include table blocks for them, but mark
them \verb+not_for SQL+.  Then the SQL backends will not construct them.

\begin{table}
\begin{center}
\begin{tabular}{l|l}
Keyword & Meaning \\
\hline
\verb+no_gen+           & Checkbox for skip this table          \\
\verb+not_for+          & Backend types which skip this table   \\
\verb+sequence+         & Name of sequence block for this table \\
\verb+foreign_display+  & How other tables see our rows         \\
\verb+model_base_class+ & What model inherits from              \\
\end{tabular}
\end{center}
\caption{Table statements in tentmaker (similar
         to Table \ref{tab:tablestats2}).}
\label{tab:tablestats1}
\end{table}

\begin{figure}
\begin{center}
\includegraphics[width=4in]{tableedit}
\end{center}
\caption{Editing a table in tentmaker (same as Figure \ref{fig:tableedit1}).}
\label{fig:tableedit2}
\end{figure}

You should probably have a
\verb+foreign_display+.\index{foreign display@\verb+foreign_display+}
It governs the sort order
of the table when users see all the rows.  It is also the summary users
see when other tables refer to this one via a foreign key.  For example,
if users will select one row from this table as the foreign key value of
another table, this is what they will see in the pull down menu.

The format for \verb+foreign_display+ is simple.  If an ident follows a
percent sign immediately (without intervening whitespace), it must
be a column name which will be interpolated at that point.  Everything
else, including trailing percents, is literal.  A common example is
\verb+%last_name, %first_name+, but you can do whatever you like.

Most models should inherit from the default base class, which depends on
the Model backend you choose on the `Backends' tab.  If all of your models
need to inherit from a different base, change it once on the `Backends' tab.
If just this table needs a different base, enter the fully qualified
parent module name in the \verb+model_base_class+ box.

If you used a sequence (which we are moving away from) enter its name
in the \verb+sequence+\index{sequences!in bigtop tables}
box.  If you had tentmaker build the sequence for
you, it should have filled that in.

Though tables have statements, their main purpose in life is to house
fields.  Fields become columns in the database table and (usually) entry
widgets on the screen.
When you open a field for editing, you see something like Figure
\ref{fig:fieldedit2}.
There are many statements that affect fields, these are summarized in
Tables \ref{tab:fieldstats2} and \ref{tab:fieldhtmlstats2}.\begin{footnote}
The names in Table \ref{tab:fieldhtmlstats2} are truncated.  Their common
prefix is \verb+html_form_+.
\end{footnote}
The \verb+not_for+ statement
works for fields just as it does for tables.  For example, this is useful
if you have a column called id which is not the primary key, a situation
that confuses some ORMs.

\begin{figure}
\begin{center}
\includegraphics[width=4in]{fieldedit}
\end{center}
\caption{Editing a field in tentmaker (same as Figure \ref{fig:fieldedit1}).}
\label{fig:fieldedit2}
\end{figure}

\begin{table}
\begin{center}
\begin{tabular}{l|l}
Keyword & Meaning \\
\hline
\verb+no_gen+           & boolean for skip this field        \\
\verb+not_for+          & backends which skip this field     \\
\verb+is+               & SQL column definition clauses      \\
\verb+refers_to+        & foreign table this field refers to \\
\verb+label+            & on screen label for field          \\
\verb+non_essential+    & boolean for delayed fetch          \\
\verb+date_select_text+ & link text for popup calendar       \\
\end{tabular}
\end{center}
\caption{Field statements (similar to Table \ref{tab:fieldstats1}).}
\label{tab:fieldstats2}
\end{table}

\begin{table}
\begin{center}
\begin{tabular}{l|l}
Keyword & Meaning \\
\verb+html_form_+... & \\
\hline
\verb+type+          & form element type                        \\
\verb+optional+      & boolean for whether the user can skip it \\
\verb+constraint+    & Data::FormValidator constraint           \\
\verb+default_value+ & default form element value               \\
\verb+cols+          & cols attribute of textarea HTML element  \\
\verb+rows+          & rows attribute of textarea HTML element  \\
\verb+display_size+  & size attribute of text HTML element      \\
\verb+options+       & pull down menu choices                   \\
\end{tabular}
\end{center}
\caption{Field html form statements (similar to
Table \ref{tab:fieldhtmlstats1}).}
\label{tab:fieldhtmlstats2}
\end{table}

The \verb+is+ statement accepts SQL phrases for the column definition.
The most common value is
\verb+varchar+,\index{varchar}
which the backends will translate
to a good string type, if your database doesn't understand it.
Put as many items in the
\verb+is+\index{is table statement@\verb+is+ table statement}
statement as you like, one per
box.  There are two highly special items: \verb+primary_key+ and \verb+auto+.
Use \verb+primary_key+\index{primary key@\verb+primary_key+}
to specify your primary key(s).  We almost never use
multi-column primary keys, but Bigtop and Gantry support them to an extent.
Repeat \verb+primary_key+ for each field which should be in the
combined key.  You don't need a primary key at all, but not having one
can make it more difficult to work with the table.

Use \verb+auto+\index{auto, primary key incrementing}
to indicate that the primary key should be incremented
by the database.  Exactly how that happens is up to the SQL backend
for your database.  But, it won't work if there are multiple columns
in the primary key.

The \verb+refers_to+\index{refers to@\verb+refers_to+}
statement indicates that this column is a foreign
key pointing to another table.  Enter the other table's name as the value.

The \verb+label+ is what the user sees when the field is on screen.

Choose the HTML form element type with
\verb+html_form_type+.\index{html form table statements}
The display option is not an input element
type.  It indicates that the field's value should be shown, but that
users will not be able to edit it.

I think you can guess what \verb+html_form_optional+ means, but I'll
say it anyway.  Check this box if you want
Data::FormValidator\index{Data::FormValidator}
to consider the field optional.  By default, all fields on
a form are required.

The \verb+html_form_constraint+ is passed to Data::FormValidator,
see its docs for details of what you can put in it.  The short answer
is a regex, a method which returns a regex, or a code ref which returns
1 when the value is good or \verb+undef+ otherwise.

Any \verb+html_form_default_value+ will be used by the form template
when there is nothing better available.  It must be a literal string or number.

The following become attributes of the html form elements:
\verb+html_form_cols+, \verb+html_form_rows+, and
\verb+html_form_display_size+.
The last one becomes the \verb+size+ attribute
of a text input area, since Template Toolkit has a virtual method called
size.

Use \verb+html_form_options+ for fields whose
\verb+html_form_type+ is select, unless the field is a foreign key.
Foreign key fields have good generated selections drawn from the
foreign table.
The `Label' of an \verb+html_form_options+ entry is what the user
sees.  The `Database Value' is what goes into the database.  As you
enter options, more boxes appear underneath.  Options appear in the
order they appear in tentmaker.  If you make an error in ordering,
it is usually easier to fix it in a text editor.  If your field has
SQL type boolean, use `t' and `f' for the database values.  Numbers
are a bad choice.

If you want to use a popup date calendar, for a field of type date,
enter
\verb+date_select_text+.\index{date select text@\verb+date_select_text+}
If you change a field's type to
date in tentmaker, this will be set to `Select Date' for you.

Some ORMs use lazy column fetching.  If yours does, and the current column
should be fetched lazily,\footnote{only when an accessor for it is called}
check the
\verb+non_essential+\index{non-essential columns@\verb+non_essential+}
box.

\subsubsection{Controller and Base Controller}

Each controller\index{controller!editing in tentmaker}
represents a pair of code modules: a stub\index{stub controller}
module and a GEN\index{GEN controller}
module.  Once written, stubs are never overwritten.  The only ways to get
bigtop to regenerate a stub module are to remove or rename it.

When you edit a controller, you'll something like Figure
\ref{fig:controledit2}.  The statements revealed there are
summarized in Table \ref{tab:controlstats2}.
Base Controllers\index{base controller!editing in tentmaker}
are similar, but they accept fewer statements.  They control
the base module (the one named the same as the app) and its GEN pair.

\begin{figure}
\begin{center}
\includegraphics[width=4in]{controledit}
\end{center}
\caption{Editing a controller in tentmaker (same as
Figure \ref{fig:controledit1}).}
\label{fig:controledit2}
\end{figure}

\begin{table}
\begin{center}
\begin{tabular}{l|l}
Keyword & Meaning \\
\hline
\verb+no_gen+           & boolean for skip this controller             \\
\verb+location+         & absolute location to this controller         \\
\verb+rel_location+     & location for this controller relative        \\
                        & to base controller                           \\
\verb+controls_table+   & name of controlled table                     \\
\verb+gen_uses+         & modules used by this controller's            \\
                        & gen module                                   \\
\verb+stub_uses+        & modules used by this controller's stub       \\
\verb+uses+             & modules used by this controller's            \\                               & modules                                      \\
\verb+text_description+ & for AutoCRUD on screen prompting             \\
\verb+page_link_label+  & nav link label for page                      \\
\end{tabular}
\end{center}
\caption{Controller statements (similar to Table \ref{tab:controlstats1}).}
\label{tab:controlstats2}
\end{table}

If you want to skip just one controller, check \verb+no_gen+ for it.

For normal controllers, you must supply either a
\verb+location+\index{location} or
\verb+rel_location+\index{rel location@\verb+rel_location+}.
\verb+location+ is absolute, \verb+rel_location+ is relative to the
base location for the app.  Base controllers don't have to have an explicit
location -- the default is / -- and they are not allowed to have a relative
location.  There is nothing for them to be relative to.

Most controllers control a single table, enter its name in the
\verb+controls_table+ box (if it isn't already there).

If your controller needs external modules,\index{controller!uses}
put them in \verb+gen_uses+,\index{gen uses@\verb+gen_uses+}
\verb+stub_uses+,\index{stub uses@\verb+stub_uses+}
or \verb+uses+\index{uses@\verb+uses+}
boxes, the later appear in both gen and
stub modules.  Keep in mind that \verb+stub_uses+ and \verb+uses+ only
apply in the stub if they are in place before initial generation.  Stubs
are never overwritten.

The \verb+text_description+\index{text description@\verb+text_description+}
fills in the blank in several sentences for
AutoCRUD.

If you want this controller to appear in site navigation links, give
it a \verb+page_link_label+.\index{page link label@\verb+page_link_label+}
The user will click this label to advance
to this controller's page.

If you have your own ORM scheme, which you want to use with AutoCRUD, but
it doesn't have a Bigtop model backend, specify an
\verb+autocrud_helper+.\index{auto crud helper@\verb+autocrud_helper+}
It must be
a module which responds to the expected API.  See Chapter \ref{chap:fullcrud}
for advice.

In addition to the statements in a controller block, there are methods.
When you open a method\index{method!editing in tentmaker}
for editing you see something like Figure
\ref{fig:stubmethodedit}.

\begin{figure}
\begin{center}
\includegraphics[width=4in]{stubmethodedit}
\end{center}
\caption{Editing a method in tentmaker.}
\label{fig:stubmethodedit}
\end{figure}

There are four categories of methods:\index{method!types}
stubs,\index{stub methods} main listings, forms, and links.
A stub is just that.  A typical one looks like this:

{\footnotesize
\begin{verbatim}
#------------------------------------------------------------
# $self->stub_name(  )
#------------------------------------------------------------
sub stub_name {
    my ( $self ) = @_;
}
\end{verbatim}
}

The legal statements for methods are summarized in
Table \ref{tab:methodstats2}.
You can check \verb+no_gen+ for any method type, causing the backend
to skip it.  You can also supply
\verb+extra_args+\index{extra args@\verb+extra_args+}
for any type.  These
are added to the end of the argument list at the top of the method
(and in the docs).  Put one argument in each box, remember to include
the sigil.  Further, realize that if the argument is an array, it must
go at the end.

\subsubsection{stub methods}

Stub methods are not that much use.  Keep in mind that they only go in
stub modules, so they won't be added once the controller is initially
generated.  The other types are more useful.

\subsubsection{main listing methods}

\begin{figure}
\begin{center}
\includegraphics[width=4in]{main_listingout}
\end{center}
\caption{Sample main list output.}
\label{fig:main_listingout}
\end{figure}

\begin{table}
\begin{center}
\begin{tabular}{l|l}
Keyword & Meaning \\
\hline
\multicolumn{2}{l}{All Types} \\
\hline
\verb+no_gen+         & Skip this method                             \\
\verb+extra_args+     & extra params sub should accept               \\
\hline
\multicolumn{2}{l}{\texttt{main\_listing}} \\
\hline
\verb+cols+           & columns in main listing                      \\
\verb+cols_labels+    & column labels                                \\
\verb+header_options+ & main table heading options (Add)             \\
\verb+row_options+    & options for each main table row              \\
                      & (Edit, Delete)                               \\
\verb+limit_by+       & foreign key whose value controls             \\
                      & which rows appear                            \\
\hline
\multicolumn{2}{l}{\texttt{main\_listing} and links} \\
\hline
\verb+title+          & browser title for main listing page          \\
\verb+html_template+  & what to use instead of results.tt            \\
                      & or main.tt                                   \\
\hline
\multicolumn{2}{l}{forms} \\
\hline
\verb+extra_keys+     & extra keys for returned form hash            \\
\verb+fields+         & list of fields to include on form            \\
\verb+all_fields_but+ & list of fields to exclude from form          \\
\verb+fields+         & name attribute of HTML form element          \\
\end{tabular}
\end{center}
\caption{Method statements (similar to Table \ref{tab:methodstats1}).}
\label{tab:methodstats2}
\end{table}

The main listing\index{main listing!method editing}
output typically shows all the rows from the controlled table
as shown in Figure \ref{fig:main_listingout}.
If you want to show only so many rows per page, supply either an integer
number of
\verb+rows+\index{rows!main listing pagination}\index{main listing!pagination}
or a \verb+paged_conf+\index{paged conf@\verb+paged_conf+, main listing
pagination} variable name.  If you
specify rows, you always get that many.  If you want to control the
number of rows via a configuration variable (or any accessor) enter the
conf variable (or accessor) name as the value for \verb+paged_conf+.

The \verb+cols+\index{cols, main listing}
become columns of the main listing table.  By
default, these columns are labeled with their fields' labels.  If you want
to change the label just for the main listing, enter your alternate
labels in the
\verb+col_labels+\index{col labels@\verb+col_labels+, main listing}
boxes.  Of course, these must be in the
same order as the \verb+cols+.  Less obviously, skipped boxes are ignored,
not counted.  If you don't supply the same number of labels as their
are columns, the extras will revert to default naming.

At the far right of the main listing output in Figure
\ref{fig:main_listingout}, is a link labeled `Add.'  That is one of the
\verb+header_options+.\index{header
options@\verb+header_options+}\footnote{often there is only
one option}
You can have as many of these as you like.
Normally, they will be handled by a method in the same controller as
the main listing.  The name of the method will be the same as the
label, but in lower case.  If you want a different method to handle
the action, put its location in the
`Location,'\index{location!of header option}
column.  Even if
some of the `Labels' have alternate `Locations,' the others don't have to
specify locations.

When you supply locations, they must be valid perl code.  They will
be used exactly as you supply them.  The Gantry site object \verb+$self+,
is in scope in that code.  You may call any methods you like on it.
For instance you might like \verb+$self->app_rootp+ or \verb+$self->location+.

The \verb+row_options+\index{row options}
are similar to \verb+header_options+, but they
apply to each row in the listing.  The most common of these are `Edit'
and `Delete.'  The rules for their locations are the same as for
\verb+header_options+.
If you construct your own locations, remember to include
\verb+$id+ at the end of the URL, or in a query string.  That variable
will be in scope for your code and it will store the id of the row
to be edited or deleted.  If you fail to include \verb+$id+, the row
will be unknown at edit and delete time.

Use \verb+limit_by+ to create a \verb+do_main+ that shows only some
rows from the controlled table.  Use a foreign key field name as the
value for this statement.  If the generated \verb+do_main+ is called
with a parameter, only rows with that foreign key value will appear in
the output.  If the parameter is omitted, all rows still appear.

The \verb+title+\index{title, in main listing}
is the browser window title.  The
\verb+html_template+\index{html template@\verb+html_template+}
defaults to \verb+results.tt+,\index{results.tt@\texttt{results.tt},
default for main listings}
change it if you like.

\subsubsection{form methods}

Other statements apply to form methods.\index{form method statements}
Note that form methods
come in two kinds.  One is for use with AutoCRUD, the other for CRUD.
Their statements are exactly the same.  They only differ in how they
capture their arguments, because CRUD and AutoCRUD use different
calling conventions.

The key feature of a form is that it displays a set of entry fields for
columns in the underlying database table.  The first step in setting
one up is to pick the fields.  There are two ways to do that.  Either
enter the fields you want, each one in its own
\verb+fields+\index{fields!in form methods}
input box;
or enter the fields you don't want, each one in its own
\verb+all_fields_but+\index{all fields but@\verb+all_fields_but+}
input box.  I usually do that latter.  That makes it less work when
new fields are added to the table, because in the normal case I want to
enable users to update the new fields.

Form methods build hashes which are passed to templates.  Some templates --
including the default \verb+form.tt+ supplied by Gantry -- allow additional
hash keys tentmaker doesn't know about.  The
\verb+extra_keys+\index{extra keys@\verb+extra_keys+}
take care
of this case. Recall that Section \ref{sec:asciiart} has an example involving
a popup calendar.

If your form needs a name (e.g. for CSS use or a popup calendar), enter
it in the \verb+form_name+\index{form name method} input box.

\subsubsection{link methods}

To make your base controller display site navigation links with its
\verb+do_main+\index{do main@\verb+do_main+!in base controllers} method,
use method type
\verb+base_links+.\index{base links@\verb+base_links+!method type}
The statements for base links methods are a subset of the statements
for main listings.

Most of our base controllers provide site navigation links through a method,
so the wrapper template can show them on each page.  If you want such
a method use method type \verb+links+.\index{links, method type}
These have no special
statements.

Those are all the statements that apply to methods.  With them, we have
finished talking about controller edits.  But, there are other things
bigtop allows in controllers, which are not understood by tentmaker.
These include controller level literals and config blocks.  See Chapter
\ref{chap:bigsyntax} for details.

\subsubsection{Literal}
\label{sssec:tentliteral}

Literals\index{literal!editing in tentmaker}
are taken literally.  Each one is understood by at least one backend
or backend family.  They take text directly from your Bigtop source file
and dump it into their output.
There are several literal types, Table \ref{tab:applits} shows them along
with an explanation of where their output goes.
Note that all of the literal types are always legal, but they will be ignored
unless a loaded backend understands them.

\begin{table}
\begin{center}
\begin{tabular}{l|l}
Literal Type & Output Destination \\
\hline
SQL       & \verb+docs/schema.*+, for all of your SQL backends \\
Location  & the base module location in httpd.conf made by \\
          & HttpdConf Gantry \\
HttpdConf & between locations in httpd.conf made by \\
          & HttpdConf Gantry \\
PerlTop   & immediately below the shebang line in \verb+<Perl>+ \\
          & block of httpd.conf or immediately below the        \\
          & shebang line in CGI or stand alone                  \\
          & server scripts                                      \\
PerlBlock & inside the \verb+<Perl>+ block of httpd.conf \\
Conf      & at the top level of Config::General conf file \\
\end{tabular}
\end{center}
\caption{App level literal types and where their output goes.}
\label{tab:applits}
\end{table}

When I said that literals are taken literally, I left out one obscure,
but pleasant, exception.  If your literal does not end with whitespace,
one new line will be added to it in the output.  Otherwise, they are
taken as written.  But, note that how they look in the input box on
the `App Body' tab of tentmaker may be deceiving, since some characters
are not visible there (like trailing spaces).  To be sure of what is
in your literal, look at the `Current bigtop file' dump on the `Bigtop
Config' tab or look at the Bigtop file with a text editor.

\subsubsection{Join Table}

A join
table\index{join table!editing in tentmaker}\index{many-to-many!in tentmaker}
is needed whenever two tables share a many-to-many
relationship.  This table will have three columns: its own id
and the foreign key ids of the many-to-many tables.  Editing a join
table looks like Figure \ref{fig:joiner}.  Its two statements are
summarized in Table \ref{tab:jointablestats2}.

\begin{figure}
\begin{center}
\includegraphics[width=4in]{joiner}
\end{center}
\caption{Editing a join table in tentmaker.}
\label{fig:joiner}
\end{figure}

\begin{table}
\begin{center}
\begin{tabular}{l|l}
Keyword & Meaning \\
\hline
\verb+joins+ & (Required) which tables are being joined \\
\verb+names+ & what the relationships should be called \\
\end{tabular}
\end{center}
\caption{Join table statements (similar to Table \ref{tab:jointablestats1}).}
\label{tab:jointablestats2}
\end{table}

When using a join table, you must specify the names of the tables it
\verb+joins+.
The relationship is completely symmetric, so the order
you list them in makes no difference.

Each side of a many-to-many relationship needs a name.  Normally, the
name is the table name with an extra `s' added at the end.  But,
you can control the \verb+names+.\index{names of many-to-many ends}
If you pick one, you must pick the
other, even if your choice would be the default.  In Figure \ref{fig:joiner},
the \verb+names+ should probably be `foxes' and `socks.'

A join table is made for you when you use
\verb+<->+\index{many-to-many!operator}\index{$<->$@\verb+<->+}
in ASCII art for bigtop or tentmaker.  See Section \ref{sec:asciiart}, or
the first section of this chapter, for how to do that.  But, note that
for the models to have a many-to-many relationship, you need to use
the Model GantryDBIxClass backend.  It is the only one that understands
them.

\subsubsection{Sequence\index{sequences}}

If you like to use PostgreSQL sequences to auto-increment your primary key,
feel free to create a sequence for each table.  Do this at the outset,
because sequences must be defined before the tables which use them and
because creating a sequence in tentmaker makes a corresponding table
and controller.  Name the sequence with a trailing \verb+_seq+.  Then
the names of the table and controller will make more sense.

Using sequences is not a problem, even if your database does not understand
them.  The backends whose databases don't support them correctly adjust to
a sequence if it is present\footnote{by ignoring it}.

\subsection{Backends\index{tentmaker!backends tab}}

Bigtop can make lots of different things.  The Backends tab controls what
it makes for you.
When you click the `Backends' tab, you see something like Figure
\ref{fig:backends}.\index{backends!tentmaker
figure}\index{tentmaker!backends figure}
The basic idea on this tab is simple.  Check the box
for each backend you want working for you.  Once the box is checked, fill
in any values you need for that backend.  See Chapter \ref{chap:backends}
for a list of all available backends and the meaning of their configurable
values.

\begin{figure}
\begin{center}
\includegraphics[width=4in]{backends}
\end{center}
\caption{The top of the backends tabbed pane, showing one available
backend in miniature.}
\label{fig:backends}
\end{figure}

I've refrained from including additional screen shots featuring the other
backends.  The modules which support tentmaker know how to find all the
backends on your system, so any new ones will show up when you run tentmaker.
%See Chapters \ref{chap:parsing}-\ref{chap:backendanat} for how to make
%your own backends.
Since Chapter \ref{chap:backends} covers backends in detail, we'll move
along now.

\subsection{App Level Statements\index{tentmaker!App Level Statements tab}}
\label{ssec:appstat}

App level statements describe the application and its base Perl module.
You must update all of these statements before generation, except `Base
Location.'  Once the base module for the app -- or any other stub module -- is
generated, it is never regenerated.  Bigtop will cowardly refuse to
regenerate stubs.  There is no way to force it to rewrite a stub file short
of deleting or renaming it.

When you edit a default bigtop file, all the app level statements are
blank, so the `App Level Statements' table looks like Figure
\ref{fig:appstat}.  I've trimmed the figure so it will fit more
comfortably on the page.  The HTML table on your screen will have
two additional columns describing what the statement means and listing
the backends which respect it.  I've limited the figure to what fits
in the scroll pane.  Other statements are available to those willing to
scroll down.
All of the app level statements are summarized in Table
\ref{tab:appstats2}.
All of the things on this tab are optional and have fine defaults.

\begin{figure}
\begin{center}
\includegraphics[width=3.75in]{appstat}
\end{center}
\caption{Editing app level statements in tentmaker.}
\label{fig:appstat}
\end{figure}

\begin{table}
\begin{center}
\begin{tabular}{l|l}
Label & Meaning \\
\hline
No Gen            & skip all generation             \\
Base Location     & base URL absolute from doc root \\
Authors           & who works on the app            \\
Contact Us        & how to join the app             \\
Copyright Holder  & who owns the app                \\
License Text      & exact text                      \\
Modules Used      & deprecated                      \\
\end{tabular}
\end{center}
\caption{App level statements (similar to Table \ref{tab:appstats1}).}
\label{tab:appstats2}
\end{table}

Truly paranoid people might want to check the `No Gen' box.  Doing
so makes bigtop skip all generation, but it almost always causes pain in
the end.

The `Base Location'\index{Base Location}
is the beginning of the URL for all pages in the app.  It is safe to leave
it blank.  Then, all page locations will be from the document
root of the server.  You cannot use a non-trivial `Base Location' with
a stand alone server (like app.server), because it doesn't have a document
root notion.  When you do set a `Base Location,' you need to add an
\verb+app_rootp+ config variable with the same value on the `App Config'
pane (see the next subsection).

It is better to specify the base location with the \verb+location+
statement in your base controller, if you have one.  Don't do it in both
places.  I don't even know what will happen if you duplicate them.
This approach is so much better that you should consider the app level
statement deprecated.

If you never enter `Authors,'\index{authors}
the author name and email will be generated
just like h2xs generates them.  If you do enter `Authors,' you may choose
to supply email addresses.  This is why the name input boxes are colored but
the email input boxes are white.

To add a blurb about joining or contacting your project developers to
various generated docs, enter something for
`Contact Us.'\index{contact us}

If the first author is not the copyright owner, enter the proper
`Copyright Holder.'\index{copyright holder}

By default, the license text is the same as what h2xs generated for
the Perl 5.8.6 distribution.  If you want something different, enter it
in `License Text.'\index{license text}

Out of view in Figure \ref{fig:appstat} is the `Modules Used' list.
This is deprecated.  Fill in the \verb+stub_uses+, \verb+gen_uses+,
or \verb+uses+ statements in your base controller, instead of doing it here.

Keep in mind that all of these statements, except `Base Location,' are only
effective if you fill them in before initial generation.  All of their
output is destined for stub files of one kind or another, so it is not
subject to regeneration.

\subsection{App Config\index{tentmaker!App Config tab}}

Finally, we come to that last tab.
Most apps have some configuration parameters which should be kept out of
the code, enabling administrators to update them on production machines without
disturbing our beautiful modules.  The `App Config' tab lets you
specify these, as shown in Figure \ref{fig:appconfig}.

\begin{figure}
\begin{center}
\includegraphics[width=4in]{appconfig}
\end{center}
\caption{Application configuration table.}
\label{fig:appconfig}
\end{figure}

Here you see the DBI\index{DBI connection string (dsn)}
connection string.  By default\index{default database connections}
this will use SQLite
as the DBD and call the database app.db.  In earlier examples, we saw
that the stand alone app.server allows users to change this information
at the command line.  In fact, app.server pays no attention to the database
config parameters.  In CGI/FastCGI and \verb+mod_perl+, the information
from the dbconn,\index{dbconn}
dbuser\index{dbuser} (optional for SQLite),
and (optional) dbpass\index{dbpass}
variables entered here
completely governs.

By default \verb+template_wrapper+\index{template
wrapper@\verb+template_wrapper+}
is set to \verb+genwrapper.tt+.\index{genwrapper.tt@\texttt{genwrapper.tt}}
You
can change that at will to your own wrapper.  The SiteLook GantryDefault
backend makes \verb+genwrapper.tt+.  If you've rolled your own, you don't
need that backend, but you do need to set the name of your wrapper here.

If there are any other config parameters your app needs, feel free to
add them.

\section*{Summary}

Now that we know what tentmaker can already do, you are ready to think big.
But, if you prefer typing to clicking, read the next chapter.  It covers
the syntax of the Bigtop language.  Once you know that, you can type Bigtop
files directly.  More likely, you'll use the information to edit Bigtop
files made by tentmaker.

